#pragma once

#include "params.hpp"
#include "types.h"
#include "tick.h"
#include <memory>
#include <stdint.h>
#include <QObject>
#include <cstdint>


using DIR_TYPE = int8_t;
using dir_t = int8_t;

const int ALL_LEVELS = 12;
const int DATA_LENGTH = 512;
const int FUTURE_LENGTH = DATA_LENGTH;

typedef struct Lines
{
  int8_t nup = 0;
  int8_t ndn = 0;
  int64_t pos = 0;
  double u1 = 0;
  double u2 = 0;
  double d1 = 0;
  double d2 = 0;

  bool operator!=(const Lines& l) const noexcept
  {
    return (nup != l.nup || ndn != l.ndn || u1 != l.u1 || u2 != l.u2 ||
            d1 != l.d1 || d2 != l.d2);
  }
} Lines;

struct DataParam
{
  bool renew = false;
  int m_frequence = 0;
  int64_t g_start_idx = 0;
  int64_t m_posIndex = 0;
  size_t tick_size = 0;
  size_t vo_size = 0;
  time_t t1 = 0;
  time_t t2 = 0;
  Lines lines;

  price_t reverse_sapace = -1;

  char* mem_key = nullptr;
  Trade::Params* vo = nullptr;
  TICK_DATA tick = nullptr;

  time_t get_time_by_idx(const int64_t idx) const noexcept;
  price_t get_price_by_idx(const int64_t idx) const noexcept;
  int pos_2_x(const int64_t idx) const noexcept;
  int time_2_x(const time_t ts) const noexcept;
  int move_pos_delta(const int delta) noexcept;
  int set_pos(const int64_t pos) noexcept;
};

struct Pet
{
  dir_t dir = 0;
  time_t tm = 0;
  time_t t1 = 0;
  time_t t2 = 0;
  price_t hp = 0;
};

struct PetParams
{  
  Pet pet[3];
  Lines mickey_lines;
  price_t eu = 0;
  price_t ed = 0;
};

typedef struct ShowOptions
{
  bool b_shouw_future = true;
  bool b_show_tom = true;
  bool b_show_jerry = true;
  bool b_show_mickey = true;
  int8_t n_show_space_lines = false;
} ShowOptions;

extern void
to_my_lines(Trade::Lines& tl, Lines& l) noexcept;

extern int
set_params_data() noexcept;

extern int
parse_data(const char* buf);


struct Action {
  dir_t d;
  price_t hpx;
  volume_t vol;
  int who;
  int action;
  time_t tm;
  int64_t idx;
  char name[20];
  char act[20];
};

using ActionPtr = std::shared_ptr<Action>;
using ActionList = std::list<ActionPtr>;


ActionPtr get_action_in_list(const int idx) noexcept;

extern ShowOptions sos;
extern DataParam g_dp;
extern PetParams g_pets;
extern ActionList g_al;

class Sender : public QObject
{
public:
  Sender() {}
  ~Sender() {}

  Q_OBJECT
public:
Q_SIGNALS:
  void sig_received_position(const int64_t pos);
  void sig_set_pet_dir_time(const int pet_id);
  void sig_mickey_lines();
  void sig_received_action(const ActionPtr& action);
  void sig_clear_action();
  void sig_received_reverse_sapce();
};

extern Sender sender;